package com.today.step.lib;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.TextView;

import com.alibaba.fastjson.JSONObject;
import com.today.step.lib.model.LineChartViewParams;
import com.today.step.lib.model.TodayStepData;
import com.today.step.lib.view.StepHistoryChatView;

import java.util.ArrayList;
import java.util.List;

import lecho.lib.hellocharts.model.AxisValue;
import lecho.lib.hellocharts.model.PointValue;
import lecho.lib.hellocharts.model.ValueShape;

public class StepCounterActivity extends AppCompatActivity {
    private final String TAG = this.getClass().getSimpleName();
    public static final String DATE_FORMAT_DD = "dd";
    public static final String DATE_FORMAT_MM_DD = "MM月dd日";
    //循环取当前时刻的步数中间的间隔时间
    private long TIME_INTERVAL_REFRESH = 500;
    private int SHOW_HISTORY_DAYS = 7;

    private long stepSum = -1;
    private Handler mDelayHandler;
    private TextView stepTextView;
    private Messenger messengerFromService;
    private Messenger getReplayMessenger;
    private StepHistoryChatView stepHistoryChatView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_step_counter);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
    }

    @Override
    public void onContentChanged() {
        super.onContentChanged();
        initView();
    }

    @Override
    protected void onStart() {
        super.onStart();
        initStepManager();
        startStepService();
    }

    private void initView() {
        stepTextView = (TextView) findViewById(R.id.stepTextView);
        stepHistoryChatView = (StepHistoryChatView) findViewById(R.id.step_history_view);
        stepHistoryChatView.setVisibility(View.INVISIBLE);
    }

    private void initStepManager() {
        //初始化计步模块
        TodayStepManager.init(getApplication());
    }

    private void startStepService() {
        mDelayHandler = new Handler(handlerCallback);
        getReplayMessenger = new Messenger(new Handler(handlerCallback));
        Intent intent = new Intent(this, TodayStepService.class);
        bindService(intent, stepServiceConnection, Context.BIND_AUTO_CREATE);
    }

    private ServiceConnection stepServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            messengerFromService = new Messenger(iBinder);
            getTodaySteps();
            getHistorySteps();
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            Logger.i(TAG, "onServiceDisconnected, componentName=" + componentName.getShortClassName());
        }
    };

    private void getTodaySteps() {
        Logger.i(TAG, "getTodaySteps");
        Message messageToService = Message.obtain(null, TodayStepConstant.MSG_REQUEST_TODAY_STEPS);
        messageToService.replyTo = getReplayMessenger;
        try {
            messengerFromService.send(messageToService);
        } catch (RemoteException e) {
            Logger.e(TAG, e.getMessage());
        }
    }

    private void getHistorySteps() {
        Message messageToService = Message.obtain(null, TodayStepConstant.MSG_REQUEST_HISTORY_STEPS);
        Bundle bundle = new Bundle(1);
        bundle.putInt(TodayStepConstant.BUNDLE_KEY_HISTORY_DAYS, TodayStepConstant.DEFAULT_HISTORY_DAYS);
        messageToService.setData(bundle);
        messageToService.replyTo = getReplayMessenger;
        try {
            messengerFromService.send(messageToService);
        } catch (RemoteException e) {
            Logger.e(TAG, e.getMessage());
        }
    }

    private Handler.Callback handlerCallback = new Handler.Callback() {
        @Override
        public boolean handleMessage(Message message) {
            switch (message.what) {
                case TodayStepConstant.MSG_RESPONSE_TODAY_STEPS:
                    handleResponseTodaySteps(message);
                    break;
                case TodayStepConstant.MSG_RESPONSE_HISTORY_STEPS:
                    handleResponseHistorySteps(message);
                    break;
                case TodayStepConstant.MSG_REQUEST_TODAY_STEPS:
                    handleRequestTodaySteps();
                    break;
                default:
                    break;

            }
            return true;
        }
    };

    private void handleResponseTodaySteps(Message message) {
        Bundle bundle = message.getData();
        long steps = bundle.getLong(TodayStepConstant.BUNDLE_KEY_TODAY_STEPS);
        Logger.i(TAG, "handleResponseTodaySteps,steps=" + steps + ",stepSum=" + stepSum);
        if (stepSum != steps) {
            stepSum = steps;
            updateStepCount(stepSum);
        }
        mDelayHandler.sendEmptyMessageDelayed(TodayStepConstant.MSG_REQUEST_TODAY_STEPS, TIME_INTERVAL_REFRESH);
    }

    private void handleRequestTodaySteps() {
        getTodaySteps();
    }

    private void handleResponseHistorySteps(Message message) {
        Bundle bundle = message.getData();
        String stepDataListStr = bundle.getString(TodayStepConstant.BUNDLE_KEY_HISTORY_STEPS);
        Logger.i(TAG, "handleResponseHistorySteps,stepDataListStr=" + stepDataListStr);
        stepHistoryChatView.setData(generateChartViewData(stepDataListStr));
        stepHistoryChatView.setVisibility(View.VISIBLE);
    }

    private void updateStepCount(long steps) {
        Logger.e(TAG, "updateStepCount : " + steps);
        stepTextView.setText(steps + "步");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (null != stepServiceConnection) {
            unbindService(stepServiceConnection);
        }
    }

    private LineChartViewParams generateChartViewData(String stepDataJsonStr) {
        List<TodayStepData> stepDataList = JSONObject.parseArray(stepDataJsonStr, TodayStepData.class);
        LineChartViewParams params = new LineChartViewParams();
        params.setShape(ValueShape.CIRCLE);
        params.setFilled(true);
        params.setHasLabels(true);
        params.setHasPoints(true);
        params.setHasXAxes(true);
        params.setXAxesNames("");
        params.setYAxesNames("");
        params.setXAxisValues(getXAxisValue());
        params.setYAxisMaxValue(getMaxSteps(stepDataList));
        params.setHasPoints(true);
        params.setHasLabelForSelected(false);
        params.setPointValueList(getPointData(stepDataList));
        params.setColorStr("#bbd8ef");
        params.setPointColorStr("#bbd8ef");
        return params;
    }

    private List<PointValue> getPointData(List<TodayStepData> stepDataList) {
        List<PointValue> pointValues = new ArrayList<>();
        if (null == stepDataList || stepDataList.isEmpty()) {
            for (int index = 0; index < SHOW_HISTORY_DAYS; index++) {
                pointValues.add(new PointValue(index, 0));
            }
        } else {
            for (int index = 0; index < SHOW_HISTORY_DAYS; index++) {
                String date = DateUtils.getPastDate(index, TodayStepConstant.SAVE_STEPS_DATE_FORMAT_STR);
                long steps = 0;
                if (index < stepDataList.size()) {
                    TodayStepData tempData = new TodayStepData();
                    tempData.setToday(date);
                    int position = stepDataList.indexOf(tempData);
                    if (-1 == position) {
                        steps = 0;
                    } else {
                        steps = stepDataList.get(position).getStepsByDateYMD(date);
                    }
                }
                pointValues.add(new PointValue(SHOW_HISTORY_DAYS - 1 - index, steps));
            }
        }
        return pointValues;
    }

    private List<AxisValue> getXAxisValue() {
        List<AxisValue> axisValues = new ArrayList<>();
        for (int index = 0; index < SHOW_HISTORY_DAYS; index++) {
            String dateStr;
            if (index == SHOW_HISTORY_DAYS - 1) {
                dateStr = DateUtils.getPastDate(index, DATE_FORMAT_MM_DD);
            } else {
                dateStr = DateUtils.getPastDate(index, DATE_FORMAT_DD);
            }
            axisValues.add(new AxisValue(SHOW_HISTORY_DAYS - 1 - index).setLabel(dateStr));
        }
        return axisValues;
    }

    private long getMaxSteps(List<TodayStepData> stepDataList) {
        long maxSteps = 0;
        if (null == stepDataList || stepDataList.isEmpty()) {
            maxSteps = 0;
        } else {
            for (int index = 0; index < SHOW_HISTORY_DAYS; index++) {
                String date = DateUtils.getPastDate(index, TodayStepConstant.SAVE_STEPS_DATE_FORMAT_STR);
                long currentSteps = 0;
                if (index < stepDataList.size()) {
                    TodayStepData tempData = new TodayStepData();
                    tempData.setToday(date);
                    int position = stepDataList.indexOf(tempData);
                    if (-1 == position) {
                        currentSteps = 0;
                    } else {
                        currentSteps = stepDataList.get(position).getStepsByDateYMD(date);
                    }
                }
                if (currentSteps > maxSteps) {
                    maxSteps = currentSteps;
                }
            }
        }
        return maxSteps;
    }

    public static void start(Context context) {
        Intent intent = new Intent();
        intent.setClass(context, StepCounterActivity.class);
        context.startActivity(intent);
    }
}
